#include <QDebug>
#include <QApplication>
#include <QStyle>
#include <QtPlugin>
#include <QIcon>
#include <QMutex>
#include <QFileIconProvider>
#include <QPainter>
#include "IconProvider.h"

IconProvider* IconProvider::_instance = NULL;

IconProvider* IconProvider::instance()
{
    static QMutex mutex;
    if (!_instance) {
        mutex.lock();

        if (!_instance)
            _instance = new IconProvider;

        mutex.unlock();
    }
    return _instance;
}

IconProvider::IconProvider()
{
    QString themeName = QIcon::themeName();
    qDebug() << "themeName" << themeName;
    if (themeName == "hicolor"){
        QString ethemeName = getenv("E_ICON_THEME");
        if (ethemeName != "")
            QIcon::setThemeName(ethemeName);
    }
    connect(QApplication::instance(), SIGNAL(aboutToQuit()), SLOT(removeIcons()));
}

void IconProvider::removeIcons()
{
    delete _instance;
}

QIcon IconProvider::icon(IconRole role)
{
    QString name;

    switch(role){
    case Folder:        return QApplication::style()->standardIcon(QStyle::SP_DirIcon);
    case File:          return QApplication::style()->standardIcon(QStyle::SP_FileIcon);
    case ResourceGroup: name = "qrc"; break;
    case FormGroup:     name = "ui"; break;
    case PyModule:      name = "py"; break;
    default:
        return QIcon();
    }

    if (_cache.contains("folder+"+name))
        return _cache["folder+"+name];

    QImage srcPixmap = QPixmap(":/icons/icons/"+name+".png").toImage();
    QIcon folder = QApplication::style()->standardIcon(QStyle::SP_DirIcon);
    //qDebug() << folder << folder.isNull() << folder.name() << folder.availableSizes(QIcon::Normal, QIcon::On);

    _cache["folder+"+name] = createCompositeIcon(folder, srcPixmap);
    return _cache["folder+"+name];
}

QIcon IconProvider::createCompositeIcon(const QIcon proto, const QImage & srcPixmap)
{
    QIcon res;
    QList<QSize> sizes; sizes << QSize(16, 16) << QSize(22, 22) << QSize(32, 32);
    foreach(QSize size, sizes){
        createIcon(res, proto, size, srcPixmap, QIcon::Normal, QIcon::Off);
        createIcon(res, proto, size, srcPixmap, QIcon::Normal, QIcon::On);

        createIcon(res, proto, size, srcPixmap, QIcon::Active, QIcon::Off);
        createIcon(res, proto, size, srcPixmap, QIcon::Active, QIcon::On);

        createIcon(res, proto, size, srcPixmap, QIcon::Selected, QIcon::Off);
        createIcon(res, proto, size, srcPixmap, QIcon::Selected, QIcon::On);

        createIcon(res, proto, size, srcPixmap, QIcon::Disabled, QIcon::Off);
        createIcon(res, proto, size, srcPixmap, QIcon::Disabled, QIcon::On);
    }
    return res;
}

void IconProvider::createIcon(QIcon & dest, const QIcon & src, QSize size, const QImage & srcPixmap, QIcon::Mode mode, QIcon::State state)
{
    QPixmap pix = src.pixmap(size, mode, state);
    QPainter paint(&pix);
    paint.drawImage(pix.rect(), srcPixmap);
    paint.end();
    dest.addPixmap(pix, mode, state);
}

QIcon IconProvider::icon(const QString & iconName)
{
    if (_cache.contains("icon+"+iconName))
        return _cache["icon+"+iconName];

    if (QIcon::hasThemeIcon(iconName))
        _cache["icon+"+iconName] = QIcon::fromTheme(iconName);
    else
        _cache["icon+"+iconName] = QIcon(":/icons/icons/"+iconName+".png");

    return _cache["icon+"+iconName];
}

QIcon IconProvider::icon(const QFileInfo & info)
{
    QString ext = info.fileName().split(".").last();

    if (_cache.contains("file+"+ext))
        return _cache["file+"+ext];

    if (ext == "ui" || ext == "qrc"){
        _cache["file+"+ext] = createCompositeIcon(QApplication::style()->standardIcon(QStyle::SP_FileIcon), QPixmap(":/icons/icons/"+ext+".png").toImage());
        return _cache["file+"+ext];
    }

    QFileIconProvider prov;
    _cache["file+"+ext] = prov.icon(info);
    return _cache["file+"+ext];

    //return QApplication::style()->standardIcon(QStyle::SP_FileIcon);
}

